/**
 * Ant Design Pro v4 use `@ant-design/pro-layout` to handle Layout.
 *
 * @see You can view component api by: https://github.com/ant-design/ant-design-pro-layout
 */
import type {
    MenuDataItem,
    BasicLayoutProps as ProLayoutProps,
    Settings,
} from '@ant-design/pro-layout';
import ProLayout, { ProBreadcrumb } from '@ant-design/pro-layout';
import { useMemo } from 'react';
import { Link, useIntl, history, useModel, useAccess, traverseModifyRoutes } from 'umi';
import { BookOutlined, LinkOutlined, ToolOutlined } from '@ant-design/icons';
import RightContent from '@/components/RightContent';
import Footer from '@/components/Footer';
import defaultSettings from '../../config/defaultSettings';
import { WithExceptionOpChildren } from './component/exception';
import { getMatchMenu, transformRoute } from '@umijs/route-utils';

export type BasicLayoutProps = {
    breadcrumbNameMap: Record<string, MenuDataItem>;
    route: ProLayoutProps['route'] & {
        authority: string[];
    };
    settings: Settings;
} & ProLayoutProps;

export type BasicLayoutContext = { [K in 'location']: BasicLayoutProps[K] } & {
    breadcrumbNameMap: Record<string, MenuDataItem>;
};

const isDev = process.env.NODE_ENV === 'development';
const loginPath = '/admin/login';
const devToolLinks = [
    <Link key="dev_permission" to="/admin/dev/permission">
        <ToolOutlined />
        <span>模块初始配置</span>
    </Link>,
    <Link key="openApi" to="/api/index.html" target="_blank">
        <LinkOutlined />
        <span>OpenAPI 文档</span>
    </Link>,
    <Link key="docs" to="/~docs">
        <BookOutlined />
        <span>业务组件文档</span>
    </Link>
]

const BasicLayout = (props: any) => {
    const { children, userConfig = {}, location } = props;
    const { initialState, refresh } = useModel('@@initialState');
    const { formatMessage } = useIntl();

    // 监听App消息
    initialState?.eventHub?.on("AppNotify", (e) => {
        console.log('AppNotify', e);
    });

    initialState?.eventHub?.on("SettingsUpdate", (e) => {
        console.log('SettingsUpdate', e);
        // 刷新全局状态时需要断开 eventHub
        initialState?.eventHub?.Instance.close();
        refresh();
    });

    initialState?.eventHub?.on("UserRefresh", async (e) => {
        console.log('UserRefresh', e);
        await initialState?.refreshUserInfo?.();
        // 刷新全局状态时需要断开 eventHub
        initialState?.eventHub?.Instance.close();
        refresh();
    });

    // /**
    //  * 启用对象存储库访问ACL控制
    //  */
    // if (initialState?.settings?.storageGetAcl) {
    //     /**
    //      * 监听全局onError事件,当标签为Img时自动调用接口进行签名处理
    //      */
    //     document.addEventListener("error", function (e) {
    //         const elem = e.target;
    //         console.log('onError', e);
    //         // todo:需加入startsWith进行提前量判断
    //         if (elem instanceof HTMLImageElement) {
    //             if (/^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/]+$/.test(elem.src)) {
    //                 getApiFileCenterResourceAcl({
    //                     objectUri: elem.src
    //                 }).then(({ data: aclUrl }) => {
    //                     console.log('aclUrl', aclUrl);
    //                     elem.src = aclUrl!;
    //                 })
    //             }
    //             e.preventDefault();
    //         }
    //     }, true);
    // }

    const currentPathConfig = useMemo(() => {
        const { menuData } = transformRoute(
            props?.route?.routes || [],
            undefined,
            undefined,
            true,
        );
        // 动态路由匹配
        return getMatchMenu(location.pathname, menuData).pop() || {};
    }, [location?.pathname, props?.route?.routes]);

    const access = useAccess?.();

    return (
        <ProLayout
            logo={initialState?.settings?.logo}
            formatMessage={formatMessage}
            {...props}
            {...defaultSettings}
            title={initialState?.settings?.title}
            onMenuHeaderClick={(e) => {
                e.stopPropagation();
                e.preventDefault();
                history.push('/admin')
            }}
            menuItemRender={(menuItemProps, defaultDom) => {
                if (menuItemProps.isUrl) {
                    return defaultDom;
                }
                if (menuItemProps.path && location.pathname !== menuItemProps.path) {
                    return (
                        <Link to={menuItemProps.path} target={menuItemProps.target}>
                            {defaultDom}
                        </Link>
                    );
                }
                return defaultDom;
            }}
            breadcrumbRender={(routers = []) => [
                {
                    path: '/admin',
                    breadcrumbName: initialState?.settings?.name ?? 'Home',
                },
                ...routers,
            ]}
            waterMarkProps={{
                content: initialState?.settings?.name,
            }}
            disableContentMargin={false}
            itemRender={({ path, breadcrumbName }) => (
                <Link to={path}>{breadcrumbName}</Link>
            )}
            postMenuData={
                traverseModifyRoutes
                    ? (menuData) => {
                        const resultMenus = traverseModifyRoutes?.(menuData!, access);
// 筛选出未授权的路由
                        return resultMenus.filter(f => f.unaccessible === false).map(m => {
                            const routes = m.routes?.filter(s => s.unaccessible === false);
                            const vaildRouteCodes = routes?.map(a => a.code);
                            const _children = m.children?.filter((s: any) => vaildRouteCodes?.includes(s.code));
                            return { ...m, children: _children, routes }
                        });
                    }
                    : undefined
            }
            footerRender={() => <Footer />}
            // menuDataRender={menuDataRender}
            menuDataRender={
                userConfig.patchMenus
                    ? (menuData) => userConfig?.patchMenus(menuData, initialState)
                    : undefined
            }
            rightContentRender={() => <RightContent />}
            headerContentRender={({ layout, isMobile }, dom) => {
                if (isMobile) return false;
                else if (layout === 'top') return dom;
                else {
                    return <ProBreadcrumb {...layout === 'mix' ? {
                        style: {
                            padding: '0 5px',
                            borderRadius: 2,
                            backgroundColor: '#fff'
                        }
                    } : {}} />
                }
            }}
            menuHeaderRender={(logo, title, hProps) => {
                console.log('menuHeaderRender', logo, title, hProps);
                if (hProps?.isMobile || hProps?.layout === 'mix') return false;

                return (<>
                    <img src={initialState?.settings?.logo} style={{
                        width: 32,
                        height: 32
                    }} />
                    {title && <h1>{initialState?.settings?.name}</h1>}
                </>)
            }}
            headerTitleRender={(logo, title, hProps) => {
                console.log('headerTitleRender', logo, title, hProps);
                if (hProps?.isMobile) return false;
                return (<a style={{
                    width: 203
                }}>
                    <img src={initialState?.settings?.logo} style={{
                        width: 32,
                        height: 32
                    }} />
                    {title && <h1>{initialState?.settings?.name}</h1>}
                </a>)
            }}
            links={isDev ? devToolLinks : []}
            onPageChange={(changeLocation) => {
                // 如果没有登录，重定向到 login
                if (!initialState?.currentUser
                    && changeLocation?.pathname?.startsWith('/admin')
                    && changeLocation?.pathname !== loginPath) {
                    history.push(loginPath);
                }
                console.log('onPageChange', changeLocation, initialState?.currentUser);
            }}>
            <WithExceptionOpChildren
                noFound={userConfig?.noFound}
                unAccessible={userConfig?.unAccessible}
                currentPathConfig={currentPathConfig}
            >
                {userConfig.childrenRender
                    ? userConfig.childrenRender(children, props)
                    : children}
            </WithExceptionOpChildren>
        </ProLayout>
    );
};

export default BasicLayout;
